import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;

import javax.imageio.ImageIO;
import javax.swing.SwingWorker;
import net.semanticmetadata.lire.clustering.KMeans;
import net.semanticmetadata.lire.clustering.MyCluster;
import net.semanticmetadata.lire.clustering.MyVec;
import net.semanticmetadata.lire.imageanalysis.sift.Feature;

// INSERT INTO test.image VALUES ('one1' ,'4','c:\\project\\one\\4.jpg','jpg')

public class DataBase extends ImageProcess {

	// File representing the folder that you select using a FileChooser
    private File dir = null;
    public String path;
    private String id;
    private int numOfItr;
    SwingWorkerProgress.ProgressWorker progressWorker;
    //**private KMeans Kmeans = null; 

	

	public DataBase(String id) {
		super();
		this.id = id;
	}
    
	public DataBase(String path, String id, int numOfClusters, int maxClusterSize, int numOfItr) {
		super();
		this.path = path;
		this.id = id;
		this.dir = new File(path);
		this.numOfClusters = numOfClusters;
		this.maxClusterSize = maxClusterSize;
		this.numOfItr = numOfItr;
		}
	
	
	public int CheckID ()
	{
		try
		{
			Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/objectsretrival","root","omer11");	
			Statement stmt = conn.createStatement();
			
			// check database id
			System.out.println("check database id");
			ResultSet res=stmt.executeQuery("SELECT * FROM databaset WHERE DataBaseID='"+this.id+"';");			
			if (res.next())
				return 0;
			else
				return 1;
			}
		catch (SQLException e) {e.printStackTrace();}
		return -1;

	}
	
	public void Start (SwingWorkerProgress.ProgressWorker progressWorker)
	{
		this.progressWorker = progressWorker; 
		progressWorker.setP(3);
		createImagesList();
		progressWorker.setP(10);
		System.out.println("Create ImageList");
		CreateRegionList();
		progressWorker.setP(12);
		System.out.println("Create RegionList");
		GetVectores();
		progressWorker.setP(15);
		System.out.println("Get Vectors");
		CreatekMeans();
		System.out.println("Create Kmeans");
		RemovingStopWords();
		progressWorker.setP(75);
		System.out.println("Remov StopWords");
		CreateIndexing();
		progressWorker.setP(80);
		System.out.println("Create Indexing");
		ComputeTfIdf();
		progressWorker.setP(82);
		System.out.println("Compute TfIdf");
		InsertToTable();
		System.out.println("Insert InTo Table");
		progressWorker.setP(100);
		System.out.println("Finish");

	}
	
	public void InsertToTable() {	
		try {
			Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/objectsretrival","root","omer11");	
			Statement stmt = conn.createStatement();
			//
			// insert database table
			String databasePath = "";
			System.out.println("insert database table");
			String[] splitDataBasePath = this.path.split("\\\\");
			for (int i = 0 ; i < splitDataBasePath.length ; i++)
				databasePath = databasePath +"\\\\"+splitDataBasePath[i];
			databasePath = databasePath.substring(2);
			stmt.executeUpdate("INSERT INTO databaset VALUES ('"  + this.id + "','" + databasePath + "' ," + this.numOfClusters+ " ," + this.maxClusterSize+ ");");
		
			
			// insert cluster table
			System.out.println("insert cluster table");
			for (Entry<Integer, MyCluster> c : clustersList.entrySet()) {	
				Integer clusterId = c.getKey();
				MyCluster cluster = c.getValue();
				for (int i = 0; i < cluster.getMean().length ; i++)
				{	
					stmt.executeUpdate("INSERT INTO cluster VALUES ('"  + this.id + "','" + clusterId + "','" + i + "' ,'" + cluster.getMean()[i]+ "')");	
				}
			}
			
			/*
			// insert vector table
			System.out.println("insert vector table");
			for (Entry<String, MyVec> v : finalVecList.entrySet()) {	
				String vecId = v.getKey();
				MyVec vec = v.getValue();
				for (int i = 0; i < vec.vec.length ; i++)
				{
					
					stmt.executeUpdate("INSERT INTO vector VALUES ('"  + this.id + "','" + vecId + "','" + vec.clusterId + "','" + i + "' ,'" + vec.vec[i]+ "','"+ vec.x+"','"+vec.y+"')");	
				}
			}
			*/
			
			// insert image table
			System.out.println("insert image table");
			for (Entry<String, MyImage> d : finalImagesList.entrySet()) {
			    String imageId = d.getKey();
			    MyImage img = d.getValue();
			    String imgPath = "";
				System.out.println("insert database table");
				String splitImgPath[] = img.getLocation().split("\\\\");
				for (int i = 0 ; i < splitImgPath.length ; i++)
					imgPath = imgPath +"\\\\"+splitImgPath[i];
				imgPath = imgPath.substring(2);
				stmt.executeUpdate("INSERT INTO image VALUES ('"+ this.id + "' ,'"  + imageId + "','" + imgPath + "','" + img.getType()+ "')");	
				
				// insert tfidf table
				System.out.println("insert tfidf table");
				for (int i = 0; i < img.tfIdf.length ; i++)
				{
					stmt.executeUpdate("INSERT INTO tfidf VALUES ('"+ this.id + "' ,'"   + imageId + " ',' " + i + "' ,'" + img.tfIdf[i]+ "')");
				}
			}
			
			
			// insert clusterIndaexing table
			System.out.println("insert clusterIndaexing table");
			for (Entry<Integer, ClusterIndexing> cIndex : clusterIndexing.entrySet()) 
			{
				Integer clusterID = cIndex.getKey();
				ClusterIndexing clusterInd = cIndex.getValue();
				for (Entry<String, ClusterInImage> cInImg: clusterInd.clusterInImageList.entrySet()) 
				{
					ClusterInImage clusterInImage = cInImg.getValue();
					stmt.executeUpdate("INSERT INTO clusterindexing VALUES ('"+ this.id + "' ,"   + clusterID + " ,'" + clusterInImage.imageName+"'," + clusterInImage.count+")");	
				}
			}
		}
		catch (SQLException e) {e.printStackTrace();}
		
	}


	public void createImagesList () {


	    // array of supported extensions (use a List if you prefer)
	    final String[] EXTENSIONS = new String[]{
	        "gif", "png", "bmp", "jpg" // and other formats you need
	    };
	    // filter to identify images based on their extensions
	    FilenameFilter IMAGE_FILTER = new FilenameFilter() {

	        @Override
	        public boolean accept(File dir, String name) {
	            for (String ext : EXTENSIONS) {
	                if (name.endsWith("." + ext)) {
	                    return (true);
	                }
	            }
	            return (false);
	        }
	    };
	    
	    
	    if (dir.isDirectory()) { // make sure it's a directory
	    	for (final File f : dir.listFiles(IMAGE_FILTER)) {
	    		BufferedImage img = null;
	    		try {
	    			img = ImageIO.read(f);
	    		
	    				MyImage image = new MyImage(f.getName(), f.getPath());
	    				imagesList.put(image.getName(),image);
	    				//HashMap<String,Region> tmpRegionsList = image.getRegionList();
	    				//regionsList.putAll(tmpRegionsList);
	                } catch (final IOException e) {
	                    // handle errors here
	                }
	            }
	        }
	    }
	
	public void CreateIndexing(){

		for (Entry<Integer, MyCluster> i : clustersList.entrySet()) {
	
			Integer clusterId = i.getKey();
			ClusterIndexing index = new ClusterIndexing(clusterId);
			for (Entry<String, MyVec> k : finalVecList.entrySet()) {
		    	String vecId = k.getKey();
		    	MyVec vec = k.getValue();
		    	String[] sId = vecId.split("-");
		    	if (sId[3].equals(clusterId.toString()))
		    	{
		    		if (index.clusterInImageList.containsKey(sId[0]))
		    		{
		    			ClusterInImage c = index.clusterInImageList.get(sId[0]);
		    			c.count++;
		    			index.clusterInImageList.remove(sId[0]);
		    			index.clusterInImageList.put(sId[0], c);
		    		}
		    		else
		    		{
		    			ClusterInImage c = new ClusterInImage(sId[0]);
		    			index.clusterInImageList.put(sId[0], c);
		    		}
		    	}
		    		
			}
			clusterIndexing.put(clusterId, index);
			
		}
		
	}

	public void CreatekMeans () {
		Kmeans = new KMeans(numOfClusters);
		
		for (Entry<String, MyVec> entry : vecList.entrySet()) {
		    String key = entry.getKey();
		    MyVec v = entry.getValue();
			List<float[]> f = new LinkedList<float[]>();
			f.add(v.vec);
			Kmeans.addImage(v.id, f, v);
			f.clear();

		}
		Kmeans.init();
		double v = 0;
		int i = 0 ;
		
		Double count = 15.0 ;
		int h =  count.intValue();
		double v1 = Kmeans.clusteringStep();
		while (( v != v1 )&& (i < numOfItr))
		{
			progressWorker.setP(h);
			count = count + (double)50/numOfItr;
			System.out.println((double)50/numOfItr);
			h = count.intValue();
			i++;
			v1 = v;
		
			v = Kmeans.clusteringStep();
		}
		finalVecList = Kmeans.fitClusters();
		
		/*for (int i = 0; i < vecL.size(); i++)
		{
			System.out.println(vecL.get(i).id+ " - " + vecL.get(i).clusterId);
		}	
		System.out.println("almost Finnnnnnish");*/
	}

	/**
	 * @return the path
	 */
	public String getPath() {
		return path;
	}


	/**
	 * @param path the path to set
	 */
	public void setPath(String path) {
		this.path = path;
	}


	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}


	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}
	
	
}
	
	

	
	
	
	
